using System.ComponentModel;

namespace System.Windows.Controls
{
    /// <summary>
    /// Represents a <see cref="TreeGrid"/> column that hosts template-specified content in its cells and support sorting and filtration
    /// </summary>
    public class ManagedTemplateColumn : DataGridTemplateColumn, IManagedColumn
    {
        /// <summary>
        /// Identifies <see cref="SortDirection"/> dependency property
        /// </summary>
        public static readonly DependencyProperty SortDirectionProperty =
            DependencyProperty.Register("SortDirection", typeof(ListSortDirection?), typeof(ManagedTemplateColumn),
                                        new PropertyMetadata(OnSortDirectionChanged));

        private static void OnSortDirectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var column = (ManagedTemplateColumn)d;
            if (column._manager != null)
                column._manager.SetSorting((ListSortDirection?) e.NewValue, column);
            column.InvokeSortDirectionChanged();
        }

        /// <summary>
        /// Gets or sets sort direction of this column
        /// </summary>
        public ListSortDirection? SortDirection
        {
            get { return (ListSortDirection?)GetValue(SortDirectionProperty); }
            set { SetValue(SortDirectionProperty, value); }
        }

        /// <summary>
        /// Indentifies <see cref="Filter"/> dependency property
        /// </summary>
        public static readonly DependencyProperty FilterProperty =
            DependencyProperty.Register("Filter", typeof(Predicate<object>), typeof(ManagedTemplateColumn),
                                        new PropertyMetadata(OnFilterChanged));

        private static void OnFilterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var column = (ManagedTemplateColumn)d;
            if (column._manager != null)
                column._manager.SetFilter((Predicate<object>) e.NewValue, column);
            column.InvokeFilterChanged();
        }

        /// <summary>
        /// Occurs when value of <see cref="SortDirection"/> property is changed
        /// </summary>
        public event EventHandler SortDirectionChanged;

        private void InvokeSortDirectionChanged()
        {
            var handler = SortDirectionChanged;
            if (handler != null) handler(this, new EventArgs());
        }

        /// <summary>
        /// Gets or sets filtration predicate for this column
        /// </summary>
        public Predicate<object> Filter
        {
            get { return (Predicate<object>)GetValue(FilterProperty); }
            set { SetValue(FilterProperty, value); }
        }

        /// <summary>
        /// Occurs when value of <see cref="Filter"/> property is changed
        /// </summary>
        public event EventHandler FilterChanged;

        private void InvokeFilterChanged()
        {
            var handler = FilterChanged;
            if (handler != null) handler(this, new EventArgs());
        }

        private ManagedDataGridSource _manager;

        ManagedDataGridSource IManagedColumn.Manager
        {
            get { return _manager; }
            set
            {
                _manager = value;
                if (_manager == null) return;
                _manager.SetSorting(SortDirection, this);
                _manager.SetFilter(Filter, this);
            }
        }
    }
}